import { useMemo } from 'react';
import invariant from 'invariant';
import { INITIAL_SNAP_POINT } from '../components/adaptiveBottomSheet/constants';
import { AdaptiveBottomSheetProps } from '../components/adaptiveBottomSheet';

/**
 * @todo
 * replace this with `prop-types`.
 */

export const usePropsValidator = ({ index, snapPoints, enableDynamicSizing, topInset, bottomInset }: AdaptiveBottomSheetProps): void => {
  useMemo(() => {
    const isSharedValue =
      snapPoints && typeof snapPoints === 'object' && snapPoints !== null && (snapPoints as unknown as Record<string, unknown>).value !== undefined;
    const _snapPoints = isSharedValue ? (snapPoints as unknown as Record<string, unknown>).value : snapPoints;

    invariant(_snapPoints || enableDynamicSizing, "'snapPoints' was not provided! please provide at least one snap point.");

    const isArrayMode = Array.isArray(_snapPoints);

    if (isArrayMode) {
      _snapPoints.map(snapPoint => {
        const _snapPoint = typeof snapPoint === 'number' ? snapPoint : parseInt(snapPoint.replace('%', ''), 10);

        invariant(
          _snapPoint > 0 || _snapPoint === INITIAL_SNAP_POINT,
          `Snap point '${snapPoint}' is invalid. if you want to allow user to close the sheet, Please use 'enablePanDownToClose' prop.`,
        );
      });

      invariant(_snapPoints.length > 0 || enableDynamicSizing, "'snapPoints' was provided with no points! please provide at least one snap point.");

      invariant(typeof index === 'number' || typeof index === 'undefined', "'index' was provided but with wrong type ! expected type is a number.");

      invariant(
        enableDynamicSizing || (typeof index === 'number' ? index >= -1 && index <= _snapPoints.length - 1 : true),
        `'index' was provided but out of the provided snap points range! expected value to be between -1, ${_snapPoints.length - 1}`,
      );
    } else {
      const snapPointValue = _snapPoints;

      if (typeof snapPointValue === 'string') {
        invariant(snapPointValue.includes('%'), `Snap point '${snapPointValue}' is invalid. String values must be percentages (e.g., '70%').`);

        const percentage = parseInt(snapPointValue.replace('%', ''), 10);
        invariant(percentage > 0 && percentage <= 100, `Snap point percentage '${snapPointValue}' is invalid. Must be between 1% and 100%.`);
      } else if (typeof snapPointValue === 'number') {
        invariant(snapPointValue > 0, `Snap point '${snapPointValue}' is invalid. Must be greater than 0.`);
      }

      invariant(typeof index === 'number' || typeof index === 'undefined', "'index' was provided but with wrong type ! expected type is a number.");

      invariant(typeof index === 'number' ? index >= -1 : true, "'index' was provided but invalid! expected value to be >= -1.");
    }

    invariant(typeof topInset === 'number' || typeof topInset === 'undefined', "'topInset' was provided but with wrong type ! expected type is a number.");
    invariant(
      typeof bottomInset === 'number' || typeof bottomInset === 'undefined',
      "'bottomInset' was provided but with wrong type ! expected type is a number.",
    );

  }, [index, snapPoints, topInset, bottomInset, enableDynamicSizing]);
};
